package com.hnichr.ump.plan.service.impl;

import com.hnichr.ump.common.plan.Auth;
import com.hnichr.ump.common.plan.entity.*;
import com.hnichr.ump.common.plan.service.PlanAuthService;
import com.hnichr.ump.common.plan.service.PlanScheduleContentsService;
import com.hnichr.ump.common.plan.vo.ContentAttachVo;
import com.hnichr.ump.common.plan.vo.DeptVo;
import com.hnichr.ump.common.plan.vo.PlanAuthVo;
import com.hnichr.ump.common.plan.vo.PlanScheduleContentsVo;
import com.hnichr.ump.common.util.DeptUtils;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.security.entity.Dept;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
@Slf4j
public class PlanScheduleContentsServiceImpl extends BaseServiceImpl<PlanScheduleContents> implements PlanScheduleContentsService {

    @Autowired
    private PlanAuthService planAuthService;

    @Override
    @Transactional(readOnly = true)
    public List<PlanScheduleContents> list(Criteria c){
        String deptCode = DeptUtils.getDeptCode();
        if(StringUtils.isBlank(deptCode)){
            log.error(">>>>>>>>>>>>{}无部门", SecurityUtils.getLoginUsername());
            throw new RuntimeException("无部门");
        }

        PlanAuthVo planAuthVo = planAuthService.getUserAuth();
        if(planAuthVo.getView().equals(Auth.NONE)){
            return Collections.emptyList();
        }
        List<PlanScheduleContents> schedules;
        if(planAuthVo.getView().equals(Auth.ALL)){
            schedules = list(PlanScheduleContents.class,c);
        }
        else if(planAuthVo.getView().equals(Auth.DEPT)){
            schedules = JpaUtil.linq(PlanScheduleContents.class)
                    .exists(PlanScheduleContentDept.class)
                    .equalProperty("contentId","id")
                    .like("deptCode",deptCode+"%")
                    .end()
                    .where(c).list();
        }
        else{
            return Collections.emptyList();
        }
        getDept(schedules);
        return schedules;
    }

    @Override
    @Transactional(readOnly = true)
    public Page<PlanScheduleContents> listPage(Pageable page, Criteria c){
        String deptCode = DeptUtils.getDeptCode();
        if(StringUtils.isBlank(deptCode)){
            log.error(">>>>>>>>>>>>{}无部门", SecurityUtils.getLoginUsername());
            throw new RuntimeException("无部门");
        }

        PlanAuthVo planAuthVo = planAuthService.getUserAuth();
        if(planAuthVo.getView().equals(Auth.NONE)){
            return Page.empty();
        }
        Page<PlanScheduleContents> pageList;
        if(planAuthVo.getView().equals(Auth.ALL)){
            pageList = listPage(PlanScheduleContents.class,page,c);
        }
        else if(planAuthVo.getView().equals(Auth.DEPT)){
            pageList = JpaUtil.linq(PlanScheduleContents.class)
                    .exists(PlanScheduleContentDept.class)
                    .equalProperty("contentId","id")
                    .like("deptCode",deptCode+"%")
                    .end()
                    .where(c).paging(page);
        }
        else{
            return Page.empty();
        }
        getDept(pageList.getContent());
        return pageList;
    }

    @Override
    @Transactional(readOnly = true)
    public PlanScheduleContents getById(String id){
        PlanScheduleContents content = JpaUtil.getOne(PlanScheduleContents.class, id);
        List<PlanScheduleContentDept> depts = JpaUtil.linq(PlanScheduleContentDept.class).equal("contentId",content.getId()).list();
        content.setDeptList(depts);
        return content;
    }

    @Override
    @Transactional
    public PlanScheduleContents save(PlanScheduleContentsVo vo){
        PlanScheduleContents content = new PlanScheduleContents();
        content.setDeptList(new ArrayList<>());
        BeanUtils.copyProperties(vo,content);
        JpaUtil.save(content);
        saveDept(vo,content);
        return content;
    }

    @Override
    @Transactional
    public PlanScheduleContents edit(PlanScheduleContentsVo vo){
        PlanScheduleContents content = new PlanScheduleContents();
        content.setDeptList(new ArrayList<>());
        BeanUtils.copyProperties(vo,content);
        JpaUtil.update(content);

        List<PlanScheduleContentDept> depts = JpaUtil.linq(PlanScheduleContentDept.class).equal("contentId",content.getId()).list();
        if(CollectionUtils.isNotEmpty(depts)){
            for(PlanScheduleContentDept p:depts){
                JpaUtil.delete(p);
            }
        }
        saveDept(vo,content);
        return content;
    }

    @Override
    @Transactional
    public void remove(String ids){
        String [] ida = StringUtils.split(ids,",");
        for(String id:ida){
            List<PlanSchedulesDept> planSchedulesDepts = JpaUtil.linq(PlanSchedulesDept.class).equal("scheduleId",id).list();
            if(CollectionUtils.isNotEmpty(planSchedulesDepts)){
                for(PlanSchedulesDept p:planSchedulesDepts){
                    JpaUtil.delete(p);
                }
            }
            PlanScheduleContents planScheduleContents = JpaUtil.getOne(PlanScheduleContents.class,id);
            JpaUtil.delete(planScheduleContents);
        }
    }

    @Override
    @Transactional
    public PlanScheduleContents accomplish(String id){
        PlanScheduleContents contents = getById(PlanScheduleContents.class,id);
        contents.setStatus("1");
        JpaUtil.update(contents);
        return contents;
    }

    @Override
    @Transactional
    public PlanScheduleContents unaccomplished(String id){
        PlanScheduleContents contents = getById(PlanScheduleContents.class,id);
        contents.setStatus("0");
        JpaUtil.update(contents);
        return contents;
    }

    @Override
    @Transactional(readOnly = true)
    public List<PlanScheduleContentsAttach> attachList(String id){
        return JpaUtil.linq(PlanScheduleContentsAttach.class).equal("contentId",id).desc("createTime","id").list();
    }

    @Override
    @Transactional
    public List<PlanScheduleContentsAttach> saveAttach(ContentAttachVo contentAttachVo){
        List<PlanScheduleContentsAttach> ls = new ArrayList<>();
        for(String url:contentAttachVo.getAttachUrl()){
            PlanScheduleContentsAttach attach = new PlanScheduleContentsAttach();
            attach.setContentId(contentAttachVo.getContentId());
            attach.setAttachUrl(url);
            JpaUtil.save(attach);
            ls.add(attach);
        }
        return ls;
    }

    @Override
    @Transactional
    public void removeAttach(String ids){
        String [] ida = StringUtils.split(ids,",");
        for(String id:ida){
            PlanScheduleContentsAttach attach = JpaUtil.getOne(PlanScheduleContentsAttach.class,id);
            JpaUtil.delete(attach);
        }

    }

    private void getDept(List<PlanScheduleContents> scheduleContents){
        if(CollectionUtils.isEmpty(scheduleContents)){
            return;
        }
        for(PlanScheduleContents contents:scheduleContents){
            List<PlanScheduleContentDept> depts = JpaUtil.linq(PlanScheduleContentDept.class).equal("contentId",contents.getId()).list();
            contents.setDeptList(depts);
        }
    }

    private void saveDept(PlanScheduleContentsVo vo,PlanScheduleContents contents){
        PlanAuthVo planAuthVo = planAuthService.getUserAuth();
        if(planAuthVo.getEdit().equals(Auth.NONE)){
            log.error("{}部门权限为none,不允许保存部门信息",SecurityUtils.getLoginUsername());
            throw new RuntimeException("无部门权限");
        }

        String deptCode = DeptUtils.getDeptCode();
        if(StringUtils.isBlank(deptCode)){
            log.error(">>>>>>>>>>>>{}无部门", SecurityUtils.getLoginUsername());
            throw new RuntimeException("无部门");
        }


        List<DeptVo> deptVoList = vo.getDeptList();
        List<PlanScheduleContentDept> deptLs = new ArrayList<>();
        boolean isDeptIncluded = false;
        if(CollectionUtils.isNotEmpty(deptVoList)){
            for(DeptVo deptVo:deptVoList){
                Dept dept = JpaUtil.getOne(Dept.class,deptVo.getDeptId());
                if(dept!=null){
                    PlanScheduleContentDept contentDept = new PlanScheduleContentDept();
                    contentDept.setContentId(contents.getId());
                    contentDept.setDeptId(deptVo.getDeptId());
                    contentDept.setDeptCode(dept.getDeptCode());
                    contentDept.setDeptName(dept.getDeptName());
                    contentDept.setDeptType(deptVo.getDeptType());
                    deptLs.add(contentDept);
                    if(StringUtils.startsWith(dept.getDeptCode(),deptCode)){
                        isDeptIncluded = true;
                    }
                }
            }
        }
        if(planAuthVo.getEdit().equals(Auth.DEPT)&&!isDeptIncluded){
            throw new RuntimeException("牵头部门和配合部门均未包含本人所属部门或下级部门");
        }
        for(PlanScheduleContentDept contentDept:deptLs){
            contents.getDeptList().add(contentDept);
            JpaUtil.save(contentDept);
        }

    }
}
